﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.Space.CoreTypes
{
    /// <summary>
    /// This class represents a point in a plane space.
    /// </summary>
    [Serializable]
    public class SpacePoint : ISpaceEntry
    {
        /// <summary>
        /// The x value of the point.
        /// </summary>
        [SpaceAttribute] 
        private double x;

        /// <summary>
        /// The y value of the point.
        /// </summary>
        [SpaceAttribute] 
        private double y;

        /// <summary>
        /// Initializes a new instance of the <see cref="SpacePoint"/> class.
        /// </summary>
        public SpacePoint()
        {
            this.x = 0;
            this.y = 0;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SpacePoint"/> class.
        /// </summary>
        /// <param name="x">The x value of the point.</param>
        /// <param name="y">The y value of the point.</param>
        public SpacePoint(double x, double y)
        {
            this.x = x;
            this.y = y;
        }

        /// <summary>
        /// Gets or sets the x value of the point.
        /// </summary>
        /// <value>The x value of the point.</value>
        public double X
        {
            get { return this.x; }
            set { this.x = value; }
        }

        /// <summary>
        /// Gets or sets the y value of the point.
        /// </summary>
        /// <value>The y value of the point.</value>
        public double Y
        {
            get { return this.y; }
            set { this.y = value; }
        }

        /// <summary>
        /// Converts the current space type to a <see cref="SmartMathLibrary.Point2D"/>.
        /// </summary>
        /// <returns>The converted point.</returns>
        public Point2D ToPoint()
        {
            return new Point2D(this.x, this.y);
        }

        /// <summary>
        /// Converts the current space type to a <see cref="SmartMathLibrary.GeneralVector"/>.
        /// </summary>
        /// <returns>The converted vector.</returns>
        public GeneralVector ToVector()
        {
            GeneralVector result = new GeneralVector(2);

            result[0] = this.x;
            result[1] = this.y;

            return result;
        }

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public object Clone()
        {
            return CloneFunctions.Clone(this);
        }

        /// <summary>
        /// Compares the current <see cref="ISpaceEntry"/> to the specified <see cref="ISpaceEntry"/>.
        /// </summary>
        /// <param name="entry">The specified entry to compare.</param>
        /// <returns>
        /// If the object instances are even, the method returns true otherwise, false.
        /// </returns>
        public bool Equals(ISpaceEntry entry)
        {
            if (entry is SpacePoint)
            {
                SpacePoint  check = (SpacePoint )entry;

                return ((this.X == check.X) && (this.Y == check.Y) );
            }

            return false;
        }

        /// <summary>
        /// Compares the current <see cref="ISpaceEntry"/> to the specified <see cref="ISpaceEntry"/>.
        /// </summary>
        /// <param name="entry">The specified entry to compare.</param>
        /// <returns>
        /// If the specified object instance is lower than the current instance the method returns true otherwise,
        /// false.
        /// </returns>
        public bool LowerThan(ISpaceEntry entry)
        {
            if (entry is SpacePoint)
            {
                SpacePoint check = (SpacePoint)entry;

                return ((this.X < check.X) && (this.Y < check.Y));
            }

            return false;
        }

        /// <summary>
        /// Compares the current <see cref="ISpaceEntry"/> to the specified <see cref="ISpaceEntry"/>.
        /// </summary>
        /// <param name="entry">The specified entry to compare.</param>
        /// <returns>
        /// If the specified object instance is greater than the current instance the method returns true otherwise,
        /// false.
        /// </returns>
        public bool GreaterThan(ISpaceEntry entry)
        {
            if (entry is SpacePoint)
            {
                SpacePoint check = (SpacePoint)entry;

                return ((this.X > check.X) && (this.Y > check.Y));
            }

            return false;
        }
    }
}